<!-- 表单结构 -->
<template>
	<el-form
		:disabled="disabled"
		:inline="true"
		:label-width="labelWidth"
		:model="form"
		class="form-inline"
		ref="form"
		v-if="formLabel"
	>
		<slot name="headerItem" />
		<template v-for="item in inFormLabel">
			<!-- 标题 -->
			<div
				:key="item[formValueKey]"
				class="line-title mb-20 mlr-20"
				v-if="item.isTitle"
			>{{item.title}}</div>
			<!-- 非标题 -->
			<template v-else-if="!item.hide">
				<!-- 为空 或者 是显示文本 -->
				<el-form-item
					:key="item[formValueKey]"
					:style="{width: item.width || itemWidth}"
					class="form-item"
					v-if="item.empty"
				/>
				<!-- 标题 -->
				<p
					:key="item[formValueKey]"
					class="form-title"
					v-else-if="item.type === 'title'"
				>{{item.titleName}}</p>
				<!-- 按钮 -->
				<el-button
					:key="item[formValueKey]"
					@click="clickFun(item)"
					class="mb-20"
					type="primary"
					v-else-if="item.type === 'btn'"
				>{{item.btnName}}</el-button>
				<!-- 表单 -->
				<FormItem
					:dateType="item.dateType"
					:dealValFun="item.dealValFun"
					:disabled="item.disabled"
					:filterable="item.filterable"
					:format="item.format"
					:key="item[formValueKey]"
					:label="item[formLabelKey]"
					:labelWidth="item.labelWidth || labelWidth"
					:maxlength="item.maxlength"
					:multiple="item.multiple"
					:options="item.options"
					:pickerOptions="item.pickerOptions"
					:placeholder="item.placeholder"
					:prop="item[formValueKey]"
					:props="item.props"
					:querySearch="item.querySearch"
					:required="typeof item.required === 'boolean' ? item.required : defaultRequire"
					:rules="item.rules"
					:selectLabel="item.selectLabel"
					:selectValue="item.selectValue"
					:showAllLevels="item.showAllLevels"
					:showLabel="item.showLabel"
					:showText="showText"
					:type="item.type"
					:unit="item.unit"
					:isInt="item.isInt"
					:unlinkPanels="item.unlinkPanels"
					:valueFormat="item.valueFormat"
					:width="item.width || itemWidth"
					@change="changeFunc(item, $event)"
					@keyupEnterFun="keyupEnterFun"
					class="form-item"
					ref="formItem"
					v-else
					v-model="form[item[formValueKey]]"
				/>
			</template>
		</template>
		<slot name="footerItem" />
	</el-form>
</template>

<script>
	import FormItem from './formItem'
	export default {
		components: {
			FormItem
		},
		props: {
			// 表单项(type(字段类型),column(占列数),labelWidth(label宽度),rules(校验规则),hide(是否需要隐藏),options(选项),showAllLevels(级联是否显示所有字段))
			formLabel: Array,
			// 表单label字段key
			formLabelKey: {
				type: String,
				default: 'label'
			},
			// 表单value字段key
			formValueKey: {
				type: String,
				default: 'prop'
			},
			// 表单数据(表单数据)
			transForm: Object,
			// 显示文本（所有）
			showText: Boolean,
			// label宽度（所有）
			labelWidth: String,
			// 表单项宽度（所有）
			itemWidth: {
				type: String,
				default: '25%'
			},
			// 是否默认必填项（所有）
			defaultRequire: {
				type: Boolean,
				default: true
			},
			// 是否禁止编辑
			disabled: Boolean
		},
		data() {
			return {
				form: {},
				// 内部formLabel
				inFormLabel: [],

				formLabelMap: {}
			}
		},
		created() {
			this.init()
		},
		watch: {
			// 传入数据改变
			transForm(val) {
				if (typeof val !== 'object') return
				let form = {}
				this.formLabel.forEach(v => {
					form = this.setFormData(form, v)
				})
				this.form = form
			}
		},
		methods: {
			// 初始化
			init() {
				// 初始化表单数据
				this.initFormData()
			},
			// 初始化form表单
			initFormData() {
				let form = {}
				this.formLabelMap = {}
				this.formLabel.forEach((v, k) => {
					this.formLabelMap[v.prop] = k
					form = this.setFormData(form, v)
				})
				this.form = form
				this.inFormLabel = this.formLabel
			},
			// 设置表单数据
			setFormData(form, item) {
				if (item.empty || !item.prop) return form

				const key = item[this.formValueKey]
				form[key] = this.transForm?.[key]
				// 数据传入处理函数
				if (item.transValFun && form[key]) form[key] = item.transValFun(form[key])
				return form
			},
			// 回车事件
			keyupEnterFun() {
				this.$emit('keyupEnterFun')
			},
			// 整理获取表单数据（不用校验）
			getFormData() {
				const form = {}
				let key
				this.inFormLabel.forEach(v => {
					if (v.empty) return
					key = v[this.formValueKey]
					// 向上提交处理函数
					if (this.form[key]) form[key] = v.emitValFun ? v.emitValFun(this.form[key]) : this.form[key]
				})
				return form
			},
			// 验证后 整理获取表单数据
			validate(passCallback, failedCallback) {
				this.$refs.form.validate(valid => {
					const form = this.getFormData()
					if (valid) {
						if (passCallback) passCallback(form, valid)
					} else {
						console.log('error submit!!')
						if (failedCallback) failedCallback(form, valid)
						return false
					}
				})
			},
			validateField(callback) {
				this.$refs.form.validateField(callback)
			},
			resetFields() {
				this.$refs.formItem.forEach(v => {
					v.resetFields()
				})
				// this.$refs.form.resetFields()
			},
			clearValidate(callback) {
				this.$refs.form.clearValidate(callback)
			},
			clickFun(item) {
				if (typeof item.clickFun !== 'function') return
				item.clickFun.call(this)
			},
			changeFunc(item, val) {
				if (typeof item.changeFunc !== 'function') return
				item.changeFunc.call(this, val, item)
			}
		}
	}
</script>

<style lang="scss" scoped>
	.line-title {
		width: 100%;
		font-size: 18px;
		line-height: 100%;
		padding-left: 10px;
		border-left: 4px solid #1987fa;
		position: relative;
	}
	.form-title {
		width: 100%;
		box-sizing: border-box;
		border-left: 3px solid $color-theme;
		line-height: 1;
		margin: 10px 0 20px;
		padding-left: 10px;
		font-size: 15px;
	}
	.form-inline {
		display: flex;
		flex-wrap: wrap;
		&::v-deep {
			.el-form-item__content {
				flex: 1;
			}
			.el-select {
				display: block;
			}
			.el-cascader,
			.el-date-editor.el-input,
			.el-date-editor.el-input__inner {
				width: 100%;
			}
		}
		.form-item {
			display: flex;
			// align-items: center;
			margin-right: 0;
			padding: 0 10px;
			box-sizing: border-box;
		}
	}
</style>
